package a0.introspector;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;

/**
 * author: xiaoxu
 * --通过内省api来组装一个对象，bean对象的属性是通过对象的配置文件来获取的
 * --符合程序设计：高内聚，低耦合的原则和开闭原则（对修该关闭，对扩展开放）
 * --案例：与代码解耦，利于代码维护（只需要通过配置文件实现修改）
 **/
public class BeanFactory {
    private static Properties properties = new Properties();

    //使用静态代码块读取配置文件
    static {
        InputStream inputStream = Thread.currentThread().getContextClassLoader()
                .getResourceAsStream("a0\\introspector\\config.properties");
        try {
            properties.load(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //获取一个bean
    public static Object getBean(String name) throws Exception {
        Object bean = null;
        String beanName = properties.getProperty(name);
        Class aClass = Class.forName(beanName);
        bean = aClass.newInstance();
        //通过类信息获取bean的描述
        BeanInfo beanInfo = Introspector.getBeanInfo(aClass);
        //获取bean的【属性】信息描述器
        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();

        for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
            //获取设置属性值的方法（set）
            Method writeMethod = propertyDescriptor.getWriteMethod();
            //获取属性名字
            String propertyName = propertyDescriptor.getName();
            if ("username".equals(propertyName)) {
                //调用属性的set方法
                writeMethod.invoke(bean, properties.getProperty("bean.username"));
            } else if ("password".equals(propertyName)) {
                //调用属性的set方法
                writeMethod.invoke(bean, properties.getProperty("bean.password"));
            } else if ("url".equals(propertyName)) {
                //调用属性的set方法
                writeMethod.invoke(bean, properties.getProperty("bean.url"));
            }
        }


        return bean;
    }

}
